using System.Collections.Generic;
using System.ComponentModel;
using System.Xml.Linq;

namespace Savviety.ServiceManager.API.Criteria
{
    public abstract class Expression
    {
        protected readonly List<SimpleExpression> Expressions;
        protected XElement Root;
        public static XNamespace NameSpace = "http://Microsoft.EnterpriseManagement.Core.Criteria/";

        protected Expression()
        {
            Expressions = new List<SimpleExpression>();
            Root = GetXElement("Expression");            
        }

        public Expression AddExpression(SimpleExpression expression)
        {
            Expressions.Add(expression);
            return this;
        }

        public abstract XElement ToXElement();

        protected XElement GetRightExpression(string value)
        {
            var el = GetXElement("ValueExpressionRight");
            var prop = GetXElement("Value", value);
            el.Add(prop);
           
            return el;
        }

        public static XElement GetXElement(string elementName)
        {
            return new XElement(NameSpace+elementName);
        }

        public static XElement GetXElement(string elementName,string value)
        {
            return new XElement(NameSpace + elementName,value);
        }

        protected XElement GetLeftExpression(string value)
        {
            var el =  GetXElement("ValueExpressionLeft");
            var prop =  GetXElement("Property", value);
            el.Add(prop);
            return el;
        }

        protected XElement GetUnaryOperatorXElement(UnaryOperator unaryOperator)
        {
            switch (unaryOperator)
            {
                case UnaryOperator.IsNull:
                    {
                        return GetXElement("Operator", "IsNull");
                    }
                case UnaryOperator.IsNotNull:
                    {
                        return GetXElement("Operator", "IsNotNull");
                    }
                default:
                    throw new InvalidEnumArgumentException("Enum is not implemented");
            }
        }

        protected XElement GetOperatorXElement(ExpressionOperator expressionOperator)
        {

            switch (expressionOperator)
            {
                case ExpressionOperator.Equal:
                    {
                        return GetXElement("Operator","Equal");
                    }
                case ExpressionOperator.NotEqual:
                    {
                        return GetXElement("Operator", "NotEqual");
                    }
                case ExpressionOperator.Greater:
                    {
                        return GetXElement("Operator", "GreaterThan");
                    }

                case ExpressionOperator.Less:
                    {
                        return GetXElement("Operator", "LessThan");
                    }
                case ExpressionOperator.GreaterEqual:
                    {
                        return GetXElement("Operator", "GreaterEqual");
                    }
                case ExpressionOperator.Like:
                    {
                        return GetXElement("Operator", "Like");
                    }
                case ExpressionOperator.NotLike:
                    {
                        return GetXElement("Operator", "NotLike");
                    }
                default:
                    throw new InvalidEnumArgumentException("Enum is not implemented");

            }
        }

    }
}